package zero.tech.games.phz.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.util.Assert;

import zero.tech.core.ZeroContext;
import zero.tech.core.data.KeyVal;
import zero.tech.core.data.Resp;
import zero.tech.core.util.StringHelper;
import zero.tech.games.common.Code;
import zero.tech.games.common.TUserAccountUtil;
import zero.tech.games.common.WaterMode;
import zero.tech.games.entity.games.Club;
import zero.tech.games.entity.user.TUserAccount;
import zero.tech.games.logic.common.Room;
import zero.tech.games.logic.data.RoomStatus;
import zero.tech.games.logic.service.api.ILogicService;
import zero.tech.games.logic.util.LogicUtil;
import zero.tech.games.phz.data.PhzConfig;
import zero.tech.games.phz.data.PhzGameBase;
import zero.tech.games.phz.data.PhzRoomCache;
import zero.tech.games.phz.data.PhzTimer;
import zero.tech.games.phz.data.consts.BrokerType;
import zero.tech.games.phz.data.consts.CphOp;
import zero.tech.games.phz.data.consts.DataType;
import zero.tech.games.phz.data.consts.DelayTime;
import zero.tech.games.phz.data.consts.DelayType;
import zero.tech.games.phz.data.consts.OpType;
import zero.tech.games.phz.data.consts.PHZCMD;
import zero.tech.games.phz.data.entity.Broker;
import zero.tech.games.phz.data.entity.Card;
import zero.tech.games.phz.data.entity.Data;
import zero.tech.games.phz.data.entity.DelayOp;
import zero.tech.games.phz.data.entity.OpData;
import zero.tech.games.phz.data.entity.PlayerData;
import zero.tech.games.phz.data.entity.data.ChiData;
import zero.tech.games.phz.data.entity.data.ChouweiData;
import zero.tech.games.phz.data.entity.data.PaopaiData;
import zero.tech.games.phz.data.entity.data.PengData;
import zero.tech.games.phz.data.entity.data.TipaiData;
import zero.tech.games.phz.data.entity.data.WeipaiData;
import zero.tech.games.phz.data.entity.op.ChipaiData;
import zero.tech.games.phz.data.entity.op.CphOpData;
import zero.tech.games.phz.data.entity.op.HupaiData;
import zero.tech.games.phz.data.entity.op.PengpaiData;
import zero.tech.games.phz.data.req.ReqChipai;
import zero.tech.games.phz.data.req.ReqGuopai;
import zero.tech.games.phz.data.req.ReqHupai;
import zero.tech.games.phz.data.req.ReqHupaiGuo;
import zero.tech.games.phz.data.req.ReqOp;
import zero.tech.games.phz.data.req.ReqPengpai;
import zero.tech.games.phz.service.api.IPhzService;
import zero.tech.games.phz.util.CardUtil.CardList;
import zero.tech.games.phz.util.CardUtil.CardListList;
import zero.tech.wsnet.controller.LogicController;
import zero.tech.wsnet.data.Message;

public class RoomUtil {

	public static Boolean checkMoneyEnoughNextRound(Room room, LogicController logicController) {
		Club club = room.getClub();
		if(club!=null) {
			PhzConfig phzConfig=(PhzConfig) room.getGameConfig();
			int num=phzConfig.getMax_player();
			Assert.isTrue(num==2||num==3,"最大人数必须是2或者3");
			int uid=logicController.getId();
			long gold=logicController.getGold();
			int room_status=room.getRoom_status();
			if(room_status==RoomStatus.DEFAULT) {
				Long admission_fee=phzConfig.getAdmission_fee();
				if(gold>=admission_fee) {
					return true;
				}
			}else {
				int water_mode=phzConfig.getWater_mode();
				long need_aa=0L;
				if(water_mode==WaterMode.AA) {
					//需要预留AA抽水的钱
					need_aa=phzConfig.getWater_num();
				}
				int need_score=0;
				long base_score=phzConfig.getBase_score();
				if(phzConfig.getBird()==1) {
					//计算打鸟分数
					int bird_need=2*phzConfig.getBird_max()*(phzConfig.getMax_player()-1);//多个并列第一的情况
					need_score+=bird_need;
				}
				//计算当前输赢分数
				PhzRoomCache phzRoomCache = (PhzRoomCache) room.getRoomCache();
				Map<Integer,Integer> score_map=phzRoomCache.getTotal_score();
				List<KeyVal<Integer, Integer>>list=StringHelper.parseMapToList(score_map);
				Collections.sort(list,new Comparator<KeyVal<Integer, Integer>>() {
					@Override
					public int compare(KeyVal<Integer, Integer> o1, KeyVal<Integer, Integer> o2) {
						return o2.getV()-o1.getV();
					}
				});
				
				if(num==3) {
					KeyVal<Integer, Integer> first=list.get(0);
					KeyVal<Integer, Integer> second=list.get(1);
					KeyVal<Integer, Integer> third=list.get(1);
					if(uid==first.getK()) {
						//第一名
						need_score+=0;
					}else if(uid==second.getK()) {
						//第二名
						int win3=second.getV()-third.getV();
						int lose1=first.getV()-second.getV();
						int cha=win3-lose1;
						if(cha<0) {
							need_score+=-cha;
						}
					}else {
						//第三名
						int lose1=first.getV()-third.getV();
						int lose2=second.getV()-third.getV();
						int he=lose1+lose2;
						need_score+=he;
					}
				}else if(num==2) {
					KeyVal<Integer, Integer> first=list.get(0);
					KeyVal<Integer, Integer> second=list.get(1);
					if(uid==first.getK()) {
						//第一名
						need_score+=0;
					}else if(uid==second.getK()) {
						//第二名
						int lose1=first.getV()-second.getV();
						need_score+=-lose1;
					}
				}
				
				long need=need_score*base_score+need_aa;
				if(gold>=need) {
					return true;
				}
			}
			
			return false;
		}else {
			int uid=logicController.getId();
			TUserAccountUtil userAccountUtil=ZeroContext.getInstance(TUserAccountUtil.class);
			TUserAccount userAccount=userAccountUtil.getUserAccount(uid);
			PhzConfig phzConfig =(PhzConfig) room.getGameConfig();
			int water_mode=phzConfig.getWater_mode();
			long water_num=phzConfig.getWater_num();
			if(water_mode==WaterMode.AA) {
				if(userAccount.getDiamond()>=water_num) {
					return true;
				}
			}
			return false;
//			return true;
		}
	}

	public static void checkGameStart(Room room) {
		IPhzService phzService=ZeroContext.getInstance(IPhzService.class);
		PhzConfig phzConfig = (PhzConfig) room.getGameConfig();
		PhzTimer pdkTimer=(PhzTimer) room.getTimer();
		int bird=phzConfig.getBird();
		int room_status=room.getRoom_status();
		if(bird==1&&room_status==RoomStatus.DEFAULT) {
			//打鸟开启
			List<LogicController> birdPeopers=LogicUtil.birdPeopers(room);
			if(birdPeopers.size()==room.getMax_player()&&room.getAllControllers().size()==room.getMax_player()) {
				phzService.gameStart(room);
			}
		}else {
			//打鸟未开启
			List<LogicController> readyPeopers=LogicUtil.readyPeopers(room);
			if(readyPeopers.size()==room.getMax_player()&&room.getAllControllers().size()==room.getMax_player()) {
				phzService.gameStart(room);
			}else {
				if(room_status==RoomStatus.WAIT_NEXT_ROUND) {
					ILogicService logicService=ZeroContext.getInstance(ILogicService.class);
					//自动准备
					long now=System.currentTimeMillis();
					long lastBeginToReadyTime=pdkTimer.lastBeginToReadyTime;
					List<LogicController> notReadyPeopers=LogicUtil.notReadyPeopers(room);
					if(now-lastBeginToReadyTime>=phzConfig.getResult_wait_time()*1000) {
						for(LogicController notReadyPeople:notReadyPeopers) {
							logicService.reqReady(room,notReadyPeople);
						}
					}
				}
			}
		}		
	}

	public static List<TipaiData> doTipais(Room room, int uid) {
		List<TipaiData> tipaiDatas = new ArrayList<>();
		PhzRoomCache phzRoomCache = (PhzRoomCache) room.getRoomCache();
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PlayerData playerData = phzGameBase.getPlayers().get(uid);
		Map<Integer,Integer> nummap=CardUtil.numMap(playerData.getHands());
		for(Entry<Integer,Integer> entry:nummap.entrySet()) {
			if(entry.getValue()==4) {
				int card_id=entry.getKey();
				List<Card> list=CardUtil.findFromHandByCardId(playerData.getHands(),card_id);
				playerData.getHands().removeAll(list);
				TipaiData tipaiData=new TipaiData(uid,card_id,list);
				playerData.getBaipais().add(tipaiData);
				tipaiDatas.add(tipaiData);
				phzRoomCache.tipai_times_inc(uid);
			}
		}
		return tipaiDatas;
	}


	public static TipaiData mopaiAndTipai(Room room, Card mopai, int uid) {
		TipaiData tipaiData = null;
		PhzRoomCache phzRoomCache = (PhzRoomCache) room.getRoomCache();
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PlayerData playerData = phzGameBase.getPlayers().get(uid);
		List<Card> list=CardUtil.findFromHandByCardId(playerData.getHands(),mopai.getCard_id());
		if(list.size()==3) {
			playerData.getHands().removeAll(list);
			list.add(mopai);
			tipaiData=new TipaiData(uid,mopai.getCard_id(),list);
			playerData.getBaipais().add(tipaiData);
			phzRoomCache.tipai_times_inc(uid);
		}
		return tipaiData;
	}

	public static Data doBaipai(Room room, Card card, int uid,int type) {
		PhzRoomCache phzRoomCache = (PhzRoomCache) room.getRoomCache();
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PlayerData op_data=phzGameBase.getPlayers().get(uid);
		int next_uid=uid;
		do {
			PlayerData playerData = phzGameBase.getPlayers().get(next_uid);
			List<Card> list=CardUtil.findFromHandByCardId(playerData.getHands(),card.getCard_id());
			if(list.size()==3) {
				if(uid==next_uid&&type==OpType.MOPAI) {
					//自己提牌
					playerData.getHands().removeAll(list);
					list.add(card);
					TipaiData tipaiData=new TipaiData(next_uid,card.getCard_id(),list);
					playerData.getBaipais().add(tipaiData);
					phzRoomCache.tipai_times_inc(next_uid);
					return tipaiData;
				}else {
					//非自己跑牌
					playerData.getHands().removeAll(list);
					list.add(card);
					PaopaiData paopaiData=new PaopaiData(next_uid,card.getCard_id(),list);
					playerData.getBaipais().add(paopaiData);
					return paopaiData;
				}
			}
			
			list=CardUtil.findFromHandByCardId(playerData.getHands(),card.getCard_id());
			if(list.size()==2) {
				if(type==OpType.MOPAI) {
					if(uid==next_uid) {
						if(playerData.getQipenglist().contains(card.getCard_id())) {
							playerData.getHands().removeAll(list);
							list.add(card);
							ChouweiData chouweiData=new ChouweiData(uid,card.getCard_id(),list);
							playerData.getBaipais().add(chouweiData);
							return chouweiData;
						}else {
							playerData.getHands().removeAll(list);
							list.add(card);
							WeipaiData weipaiData=new WeipaiData(uid,card.getCard_id(),list);
							playerData.getBaipais().add(weipaiData);
							return weipaiData;
						}
					}
				}
			}
			
			//偎牌自己摸是提,别人摸是跑,别人打是跑
			List<Data> baipais=playerData.getBaipais();			
			WeipaiData weipai_find=null;
			for(Data data:baipais) {
				if(data instanceof WeipaiData) {
					WeipaiData weipaiData = (WeipaiData) data;
					if(weipaiData.getWeipailist().get(0).getCard_id()==card.getCard_id()) {
						weipai_find=weipaiData;
						break;
					}
				}
			}
			
			if(weipai_find!=null) {
				int index=baipais.indexOf(weipai_find);
				list=new ArrayList<>();
				list.addAll(weipai_find.getWeipailist());
				list.add(card);
				
				if(type==OpType.OUTCARD) {
					op_data.setForbit_chipeng(true);
					Assert.isTrue(uid!=weipai_find.getUid(),"打牌时一定打牌者不能打自己的偎牌");
					PaopaiData paopaiData = new PaopaiData(weipai_find.getUid(),card.getCard_id(), list);
					playerData.getBaipais().set(index, paopaiData);
					return  paopaiData;
				}else if(type==OpType.MOPAI) {
					if(uid==weipai_find.getUid()) {
						TipaiData tipaiData=new TipaiData(next_uid,card.getCard_id(), list);
						playerData.getBaipais().set(index, tipaiData);
						phzRoomCache.tipai_times_inc(next_uid);
						return  tipaiData;
					}else {
						PaopaiData paopaiData = new PaopaiData(next_uid,card.getCard_id(), list);
						playerData.getBaipais().set(index, paopaiData);
						return  paopaiData;
					}
				}
			}
			
			//碰牌跑
			if(type==OpType.MOPAI) {
				PengData pengpai_find=null;
				for(Data data:baipais) {
					if(data instanceof PengData) {
						PengData pengData = (PengData) data;
						if(pengData.getPengpailist().get(0).getCard_id()==card.getCard_id()) {
							pengpai_find=pengData;
							break;
						}
					}
				}
				if(pengpai_find!=null) {
					int index=baipais.indexOf(pengpai_find);
					list=new ArrayList<>();
					list.addAll(pengpai_find.getPengpailist());
					list.add(card);
					PaopaiData paopaiData=new PaopaiData(next_uid,card.getCard_id(), list);
					playerData.getBaipais().set(index, paopaiData);
					return paopaiData;
				}
			}
			next_uid=LogicUtil.getNextPosByUid(room, next_uid);
		}while(uid!=next_uid);
		return null;
	}



	public static Map<Integer, List<CphOpData>> doCphOps(Room room, Card mopai, int uid,int type,boolean checkhu) {
		Map<Integer, List<CphOpData>> cphOps=new HashMap<Integer, List<CphOpData>>();
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PhzConfig phzConfig = (PhzConfig) room.getGameConfig();
		int next_uid=uid;
		//跑胡子,打字不能胡
		if(type==OpType.OUTCARD) {
			//出牌
			next_uid=LogicUtil.getNextPosByUid(room, next_uid);
		}else {
			//摸牌
			next_uid=uid;
		}
		do {
			PlayerData playerData = phzGameBase.getPlayers().get(next_uid);
			List<CphOpData> cphOpDatas=new ArrayList<>();
			if(!playerData.isQihu()&&type==OpType.MOPAI&&checkhu) {
				//检测胡
				CphOpData hupaiOp=checkHupaiOp(playerData,mopai,phzConfig.getHupai_need());
				if(hupaiOp!=null) {
					cphOpDatas.add(hupaiOp);
				}
			}
			if(!playerData.isQihu()&&!playerData.getQipenglist().contains(mopai.getCard_id())&&!playerData.isForbit_chipeng()) {
				//检测碰
				CphOpData pengpaiOp=checkPengpaiOp(playerData,mopai);
				if(pengpaiOp!=null) {
					cphOpDatas.add(pengpaiOp);
				}
			}
			if(!playerData.isQihu()&&!playerData.getQichilist().contains(mopai.getCard_id())&&!playerData.isForbit_chipeng()) {
				//检测吃牌比牌
				CphOpData chipaiOp=checkChipaiOps(playerData,mopai);
				if(chipaiOp!=null) {
					cphOpDatas.add(chipaiOp);
				}
			}
			if(!cphOpDatas.isEmpty()) {
				cphOpDatas.add(new CphOpData(CphOp.PASS,next_uid));
				cphOps.put(next_uid, cphOpDatas);
			}
			next_uid=LogicUtil.getNextPosByUid(room, next_uid);
		}while(next_uid!=uid);
		return cphOps;
	}

	public static CphOpData checkChipaiOps(PlayerData playerData, Card mopai) {
		return checkChipaiOps(playerData.getUid(),playerData.getHands(), mopai);
	}
	
	public static void main(String[] args) {
		Set<Integer> erqishi=new HashSet<>();
		erqishi.add(2);
		erqishi.add(7);
		erqishi.add(10);
		Set<Integer> other=new HashSet<>();
		other.add(2);
		other.add(5);
		System.out.println(erqishi.containsAll(other));
	}
	public static CphOpData checkChipaiOps(int uid, List<Card> hands, Card mopai) {
		CphOpData cphOpData = null;
		List<Card> cards=new ArrayList<>();
		cards.addAll(hands);
		//移除3个的
		Map<Integer,Integer> nummap=CardUtil.numMap(cards);
		for(Entry<Integer,Integer> entry:nummap.entrySet()) {
			int card_id=entry.getKey();
			int num=entry.getValue();
			if(num==3) {
				List<Card> removes=CardUtil.findFromHandByCardId(cards, card_id);
				cards.removeAll(removes);
			}
		}
		List<List<Card>> chipailist=CardUtil.checkChipai(cards,mopai);
		if(!chipailist.isEmpty()) {
			cphOpData=new CphOpData(CphOp.CHIPAI,uid);
			for(List<Card> list:chipailist) {
				List<Card> tmp=new ArrayList<>();
				tmp.addAll(cards);
				ChipaiData chipaiData = new ChipaiData(uid);
				chipaiData.getChipailist().addAll(list);
				tmp.removeAll(list);
				int leftcount=CardUtil.findCount(tmp,mopai);
				if(leftcount==0) {
					cphOpData.getChipaiDatas().add(chipaiData);
				}else {
					List<List<List<Card>>> bipaiDatas=CardUtil.bipaiDatas(tmp, mopai);
					if(!bipaiDatas.isEmpty()) {
						chipaiData.getBipailist().addAll(bipaiDatas);
						cphOpData.getChipaiDatas().add(chipaiData);
					}
				}
			}
		}
		if(cphOpData!=null&&cphOpData.getChipaiDatas().isEmpty()) {
			return null;
		}
		return cphOpData;
	}



	public static CphOpData checkPengpaiOp(PlayerData playerData, Card mopai) {
		CphOpData cphOpData = null;
		List<Card> list=CardUtil.findFromHandByCardId(playerData.getHands(),mopai.getCard_id());
		if(list.size()==2) {
			cphOpData=new CphOpData(CphOp.PENGPAI,playerData.getUid());
			cphOpData.setPengpaiData(new PengpaiData(playerData.getUid(), list));
		}
		return cphOpData;
	}

	private static CphOpData checkHupaiOp(int uid,List<Card> hands, Card mopai,int hupai_need) {
		CphOpData cphOpData = null;
		List<Card> cards=new ArrayList<>();
		cards.addAll(hands);
		if(mopai!=null) {
			cards.add(mopai);
		}
		List<CardListList> hupailist=CardUtil.checkHupai(cards,mopai);
		if(!hupailist.isEmpty()) {
			CardListList max_huxi=findMaxHuxi(hupailist,hupai_need);
			if(max_huxi!=null) {
				cphOpData=new CphOpData(CphOp.HU,uid);
				List<List<Card>> list=new ArrayList<>();
				for(CardList cardList:max_huxi.getList()) {
					list.add(cardList.getCards());
				}
				HupaiData hupaiData = new HupaiData(uid,list);
				cphOpData.getHupaiDatas().add(hupaiData);
			}
		}
		return cphOpData;
	}
	
	private static CardListList findMaxHuxi(List<CardListList> hupailist, int hupai_need) {
		CardListList find=null;
		int max=0;
		for(CardListList cardListList:hupailist) {
			int huxi=calHuxi(cardListList);
			if(huxi>=max&&huxi>=hupai_need) {
				max=huxi;
				find=cardListList;
			}
		}
		return find;
	}
	
	private static int calHandHuxi(Room room, List<List<Card>> list,int uid) {
		PhzGameBase phzGameBase=(PhzGameBase) room.getGameBase();
		OpData opData=phzGameBase.getHupai();
		if(opData==null) {
			opData=phzGameBase.getFanpai();
		}
		int huxi=0;
		for(List<Card> cards:list) {
			if(CardUtil.sanzhangyijuhua(cards)) {
				//如果胡的牌在三张里面则按碰计算,不在则按偎计算
				if(cards.get(0).getNum()==opData.getCard().getNum()&&opData.getUid()!=uid) {
					//算碰
					if(cards.get(0).getColor()==100) {
						huxi+=1;//3张小碰牌 1胡息
					}else if(cards.get(0).getColor()==200) {
						huxi+=3;//3张大碰牌 3胡息
					}
				}else {
					//算偎
					if(cards.get(0).getColor()==100) {
						huxi+=3;//3张小偎牌 3胡息
					}else if(cards.get(0).getColor()==200) {
						huxi+=6;//3张大偎牌 6胡息
					}
				}
				
			}
			
			if(CardUtil.tonghuaerqishi(cards)) {
				if(cards.get(0).getColor()==100) {
					huxi+=3;//3张小2710牌 3胡息
				}else if(cards.get(0).getColor()==200) {
					huxi+=6;//3张大2710牌 6胡息
				}
			}
			
			if(CardUtil.tonghuaeyiersan(cards)) {
				if(cards.get(0).getColor()==100) {
					huxi+=3;//3张小123牌 3胡息
				}else if(cards.get(0).getColor()==200) {
					huxi+=6;//3张大123牌 6胡息
				}
			}
		}
		return huxi;
	}

	private static int calHuxi(CardListList cardListList) {
		int huxi=0;
		List<CardList> list=cardListList.getList();
		for(CardList cardList:list) {
			if(CardUtil.sanzhangyijuhua(cardList.getCards())) {
				if(cardList.getCards().get(0).getColor()==100) {
					huxi+=3;//3张小偎牌 3胡息
				}else if(cardList.getCards().get(0).getColor()==200) {
					huxi+=6;//3张大偎牌 6胡息
				}
			}
			
			if(CardUtil.tonghuaerqishi(cardList.getCards())) {
				if(cardList.getCards().get(0).getColor()==100) {
					huxi+=3;//3张小2710牌 3胡息
				}else if(cardList.getCards().get(0).getColor()==200) {
					huxi+=6;//3张大2710牌 6胡息
				}
			}
			
			if(CardUtil.tonghuaeyiersan(cardList.getCards())) {
				if(cardList.getCards().get(0).getColor()==100) {
					huxi+=3;//3张小123牌 3胡息
				}else if(cardList.getCards().get(0).getColor()==200) {
					huxi+=6;//3张大123牌 6胡息
				}
			}
		}
		return huxi;
	}

	public static CphOpData checkHupaiOp(PlayerData playerData, Card mopai,int hupai_need) {
		int baipai_huxi=calBaipaiHuXi(playerData.getBaipais());
		hupai_need=hupai_need-baipai_huxi;
		return checkHupaiOp(playerData.getUid(), playerData.getHands(),mopai,hupai_need);
	}

	private static void guopai(Room room) {
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		phzGameBase.getOplistmap().clear();
		phzGameBase.getChoosemap().clear();
		phzGameBase.setStep(0);
		Broker broker=phzGameBase.getBroker();
		if(broker!=null) {
			//跑胡,提胡,偎胡,臭偎胡,胡牌过
			int broker_type=broker.getBroker_type();
			int uid=broker.getUid();
			if(broker_type==BrokerType.AUTO_TIPAI_BEI_HUPAI_DADUAN) {
				tipai(room, uid);
			}else if(broker_type==BrokerType.AUTO_PAOPAI_BEI_HUPAI_DADUAN) {
				paopai(room, uid);
			}else if(broker_type==BrokerType.AUTO_WEIPAI_BEI_HUPAI_DADUAN) {
				weipai(room, uid);
			}else if(broker_type==BrokerType.AUTO_CHOUWEI_BEI_HUPAI_DADUAN) {
				notifyOutCard(room, uid);
			}else if(broker_type==BrokerType.AUTO_MOPAI_BEI_HUPAI_DADUAN) {
				Card card=(Card) phzGameBase.getBroker().getParams().get("card");
				OpData opData= (OpData) phzGameBase.getBroker().getParams().get("opData");
				mopai(room, uid, card, opData,false);
			}
			phzGameBase.setBroker(null);
		}else {
			OpData opData=phzGameBase.getFanpai();
			int op_uid=opData.getUid();
			PlayerData playerData = phzGameBase.getPlayers().get(op_uid);
			playerData.getOp_datas().add(opData);
			int next_uid=LogicUtil.getNextPosByUid(room, op_uid);
			IPhzService phzService = ZeroContext.getInstance(IPhzService.class);
			phzService.autoMopai(room, next_uid);
		}
	}

	private static int calGuopaiSize(Map<Integer, ReqOp> choosemap) {
		int count=0;
		for(ReqOp reqOp:choosemap.values()) {
			if(reqOp.getOp()==CphOp.PASS) {
				count++;
			}
		}
		return count;
	}

	private static void chipai(Room room, ReqChipai chi) {
		int uid=chi.getUid();
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		Card fan=phzGameBase.getFanpai().getCard();
		PlayerData playerData = phzGameBase.getPlayers().get(uid);
		List<Integer> chipai_ids=chi.getChipai_ids();
		List<List<Integer>> bipai_ids=chi.getBipai_ids();
		List<Card>cards=removeFromHandByIds(playerData,chipai_ids);		
		List<List<Card>> bipais=removeFromHandByBipaiCardIds(playerData, bipai_ids);
		List<Data> list=new ArrayList<>();
		List<Card> tmp=new ArrayList<>();
		tmp.addAll(cards);
		tmp.add(fan);
		ChiData chiData =new ChiData(uid,fan.getCard_id(),tmp);
		playerData.getBaipais().add(chiData);
		list.add(chiData);
		for(List<Card> bipai:bipais) {
			ChiData cData=new ChiData(uid,fan.getCard_id(),bipai);
			playerData.getBaipais().add(cData);
			list.add(cData);
		}
		phzGameBase.getOplistmap().clear();
		phzGameBase.getChoosemap().clear();
		LogicUtil.broadRoomAllControllersInclude(room, Message.build(PHZCMD.NOTIFY_BAIPAI, Resp.build(Code.OK, "吃牌",PackageUtil.packageNotifyBaipai(room,uid,list))));
		notifyOutCard(room, uid);
	}

	private static List<List<Card>> removeFromHandByBipaiCardIds(PlayerData playerData, List<List<Integer>> bipai_ids) {
		List<List<Card>> result=new ArrayList<>();
		for(List<Integer> ids:bipai_ids) {
			List<Card> removes=removeFromHandByIds(playerData, ids);
			result.add(removes);
		}
		return result;
	}

	public static CphOpData findCphOpDataByOp(int op, List<CphOpData> cphOpDatas) {
		for(CphOpData cphOpData:cphOpDatas) {
			if(cphOpData.getOp()==op) {
				return cphOpData;
			}
		}
		return null;
	}
	private static void pengpai(Room room, ReqPengpai peng) {
		int uid=peng.getUid();
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		OpData opData=phzGameBase.getFanpai();
		Card fan=opData.getCard();
		PlayerData playerData = phzGameBase.getPlayers().get(uid);
		List<Integer> pengpai_ids=peng.getPengpai_ids();
		List<Card>cards=removeFromHandByIds(playerData,pengpai_ids);		
		List<Card> tmp=new ArrayList<>();
		tmp.addAll(cards);
		tmp.add(fan);
		int card_id=fan.getCard_id();
		PengData pengData =new PengData(uid,card_id,tmp);
		playerData.getBaipais().add(pengData);
		phzGameBase.getOplistmap().clear();
		phzGameBase.getChoosemap().clear();
		LogicUtil.broadRoomAllControllersInclude(room, Message.build(PHZCMD.NOTIFY_BAIPAI, Resp.build(Code.OK, "碰牌",PackageUtil.packageNotifyBaipai(room,uid,pengData))));
		notifyOutCard(room, uid);
	}

	public static void notifyOutCard(Room room, int uid) {
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PlayerData playerData = phzGameBase.getPlayers().get(uid);
		if(playerData.isQihu()) {
			//玩家弃胡,不用打牌,下家直接摸牌
			int next_uid=LogicUtil.getNextPosByUid(room, uid);
			phzGameBase.setDelayOp(new DelayOp(next_uid, DelayType.AUTO_MOPAI,DelayTime.AUTO_MOPAI_DELAY));
			return;
		}
		//需要打一张牌,若此时手里面没有可打的,则弃胡并直接下一家摸牌
		boolean qihu=checkQihu(room,uid);
		if(qihu) {
			reqQihu(room,uid);
			//直接下一家摸牌
			int next_uid=LogicUtil.getNextPosByUid(room, uid);
			phzGameBase.setDelayOp(new DelayOp(next_uid, DelayType.AUTO_MOPAI, DelayTime.AUTO_MOPAI_DELAY));
			return;
		}
		phzGameBase.setDispatch_uid(uid);
		phzGameBase.setStep(1);
		playerData.setLast_outcard_time(System.currentTimeMillis());
		LogicUtil.broadRoomAllControllersInclude(room, Message.build(PHZCMD.NOTIFY_CHANGE_PLAYER, Resp.build(Code.OK, "出牌-换人",PackageUtil.packageNotifyChangePlayer(room,OpType.OUTCARD,null))));		
	}
	public static void reqQihu(Room room, int uid) {
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PlayerData playerData = phzGameBase.getPlayers().get(uid);
		playerData.setQihu(true);
		LogicUtil.broadRoomAllControllersInclude(room, Message.build(PHZCMD.NOTIFY_QIHU, Resp.build(Code.OK, "玩家弃胡",PackageUtil.packageNotifyQihu(uid))));
	}

	private static boolean checkQihu(Room room, int chouwei_uid) {
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PlayerData playerData = phzGameBase.getPlayers().get(chouwei_uid);
		List<Card> hands=playerData.getHands();
		Map<Integer,Integer> map=CardUtil.numMap(hands);
		boolean qihu=true;
		for(Entry<Integer,Integer> entry:map.entrySet()) {
			if(entry.getValue()<3) {
				qihu=false;
				break;
			}
		}
		return qihu;
	}
	
	
	private static List<Card> removeFromHandByIds(PlayerData playerData, List<Integer> pai_ids) {
		List<Card> removes=new ArrayList<>();
		List<Card> cards=playerData.getHands();
		for(int id:pai_ids) {
			Card remove=CardUtil.findFromCardsById(cards, id);
			removes.add(remove);
		}
		cards.removeAll(removes);
		return removes;
	}

	public static void hupai(Room room, int hupai_uid,OpData hupai) {
		PhzRoomCache phzRoomCache = (PhzRoomCache) room.getRoomCache();
		PhzGameBase phzGameBase= (PhzGameBase) room.getGameBase();
		PhzConfig phzConfig = (PhzConfig) room.getGameConfig();
		PlayerData hupai_data=phzGameBase.getPlayers().get(hupai_uid);
		phzRoomCache.hupai_times_inc(hupai_uid);
		phzGameBase.setHupai_uid(hupai_uid);
		CphOpData cphOpData=checkHupaiOp(hupai_data, hupai==null?null:hupai.getCard(),phzConfig.getHupai_need());
		phzGameBase.setHupaiData(cphOpData.getHupaiDatas().get(0));
		if(hupai!=null) {
			hupai_data.getHands().add(hupai.getCard());
			phzGameBase.setHupai(hupai);
			
			//如果当前是20或者30胡息则不重组 否则重组
			int score=RoomUtil.calHuxiByPlayerData(room,hupai_data);
			if(score!=20&&score==30) {
				//进行重组 大小吃变跑或者提
				chongzu(room,hupai_data,phzConfig,hupai);
				cphOpData=checkHupaiOp(hupai_data, null,phzConfig.getHupai_need());
				phzGameBase.setHupaiData(cphOpData.getHupaiDatas().get(0));
			}
		}
		phzGameBase.getOplistmap().clear();
		phzGameBase.getChoosemap().clear();
		
		
		LogicController logicController = room.getAllControllers().get(hupai_uid);
		IPhzService phzService = ZeroContext.getInstance(IPhzService.class);
		phzService.gameOver(room,logicController);
	}


	private static void chongzu(Room room,PlayerData hupai_data, PhzConfig phzConfig, OpData hupai) {
		Card hu_card=hupai.getCard();
		List<Data> datas=hupai_data.getBaipais();
		Data find=null;
		for(Data data:datas) {
			if(data.getType()==DataType.WEIPAI) {
				find=data;
				break;
			}
			if(data.getType()==DataType.PENGPAI) {
				find=data;
				break;
			}
		}
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		if(find!=null) {
			HupaiData hupaiData=phzGameBase.getHupaiData();
			//如果胡牌的这张牌属于大小吃胡且属于一张那个牌则需要检查该牌是否能够组成最大胡息  自己的偎牌如果该张是自己摸的则变成提,别人打的则变成跑,自己碰牌,别人打和自己摸都是变成跑
			List<List<Card>> huList = hupaiData.getHupailist();
			for(List<Card> cards:huList) {
				Set<Integer> nums=new HashSet<>();
				int count=0;
				for(Card card:cards) {
					nums.add(card.getNum());
					if(card.getCard_id()==hu_card.getCard_id()) {
						count++;
					}
				}
				if(nums.size()==1&&nums.contains(hu_card.getNum())&&count==1) {
					//找到了
					Card remove=CardUtil.findOneCardFromHandByCardId(hupai_data.getHands(), hu_card.getCard_id());
					hupai_data.getHands().remove(remove);
					datas.remove(find);
					
					if(find.getType()==DataType.WEIPAI) {
						WeipaiData weipaiData = (WeipaiData) find;
						List<Card> weilist=weipaiData.getWeipailist();
						if(hupai.getType()==OpType.MOPAI&&hupai.getUid()==hupai_data.getUid()) {
							//变成提
							List<Card> tilist=new ArrayList<>();
							tilist.addAll(weilist);
							tilist.add(remove);
							TipaiData tipaiData = new TipaiData(weipaiData.getUid(), remove.getCard_id(), tilist);
							datas.add(tipaiData);
						}else {
							//变成跑
							List<Card> paolist=new ArrayList<>();
							paolist.addAll(weilist);
							paolist.add(remove);
							PaopaiData paopaiData = new PaopaiData(weipaiData.getUid(), remove.getCard_id(), paolist);
							datas.add(paopaiData);
						}
					}else if(find.getType()==DataType.PENGPAI) {
						PengData pengData = (PengData) find;
						List<Card> penglist=pengData.getPengpailist();
						
						List<Card> paolist=new ArrayList<>();
						paolist.addAll(penglist);
						paolist.add(remove);
						PaopaiData paopaiData = new PaopaiData(pengData.getUid(), remove.getCard_id(), paolist);
						datas.add(paopaiData);
					}
				}
			}
		}
	}

	private static List<Integer> calCanOpUids(Map<Integer, List<CphOpData>> fanpaiOplistmap, int op) {
		List<Integer> uids=new ArrayList<>();
		for(Entry<Integer,List<CphOpData>> entry:fanpaiOplistmap.entrySet()) {
			List<CphOpData> list=entry.getValue();
			boolean find=false;
			for(CphOpData cphOpData:list) {
				if(cphOpData.getOp()==op) {
					find=true;
					break;
				}
			}
			if(find) {
				uids.add(entry.getKey());
			}
		}
		return uids;
	}

	private static ReqOp effectOp(Room room, OpData opData, int op, List<Integer> canop_uids) {
		PhzGameBase phzGameBase=(PhzGameBase) room.getGameBase();
		Map<Integer,ReqOp> choosemap=phzGameBase.getChoosemap();
		int next_uid=opData.getUid();
		int type=opData.getType();
		if(type==OpType.OUTCARD) {
			next_uid=LogicUtil.getNextPosByUid(room, next_uid);
		}else {
			next_uid=opData.getUid();
		}
		int uid=next_uid;
		do {
			if(canop_uids.contains(next_uid)) {
				ReqOp reqOp=choosemap.get(next_uid);
				if(reqOp==null) {
					//还未做出选择
					return null;
				}
				if(reqOp!=null&&reqOp.getOp()==op) {
					return reqOp;
				}
			}
			next_uid=LogicUtil.getNextPosByUid(room, next_uid);
		}while(next_uid!=uid);
		return null;
	}


	public static void reqHupai(Room room, LogicController controller, ReqHupai reqHupai, OpData opData) {
		int uid=controller.getId();
		PhzGameBase phzGameBase=(PhzGameBase) room.getGameBase();
		Map<Integer,ReqOp> choosemap=phzGameBase.getChoosemap();
		choosemap.put(uid, reqHupai);
		controller.getWebClient().sendMessage(Message.build(PHZCMD.RES_CPHOP, Resp.build(Code.OK, "操作成功")));
	}

	public static void reqPengpai(Room room, LogicController controller, ReqPengpai reqPengpai, OpData opData) {
		int uid=controller.getId();
		PhzGameBase phzGameBase=(PhzGameBase) room.getGameBase();
		Map<Integer,ReqOp> choosemap=phzGameBase.getChoosemap();
		choosemap.put(uid, reqPengpai);
		controller.getWebClient().sendMessage(Message.build(PHZCMD.RES_CPHOP, Resp.build(Code.OK, "操作成功")));
	}

	public static void reqChipai(Room room, LogicController controller, ReqChipai reqChipai, OpData opData) {
		int uid=controller.getId();
		PhzGameBase phzGameBase=(PhzGameBase) room.getGameBase();
		Map<Integer,ReqOp> choosemap=phzGameBase.getChoosemap();
		choosemap.put(uid, reqChipai);
		controller.getWebClient().sendMessage(Message.build(PHZCMD.RES_CPHOP, Resp.build(Code.OK, "操作成功")));
	}

	public static void reqGuopai(Room room, LogicController controller, ReqGuopai reqGuopai, OpData opData) {
		int uid=controller.getId();
		PhzGameBase phzGameBase=(PhzGameBase) room.getGameBase();
		Map<Integer,List<CphOpData>> map=phzGameBase.getOplistmap();
		List<CphOpData> canops=map.get(uid);
		PlayerData playerData = phzGameBase.getPlayers().get(uid);
		for(CphOpData cphOpData:canops) {
			int op=cphOpData.getOp();
			if(op==CphOp.PENGPAI) {
				//能够吃牌却弃吃
				if(!playerData.getQichilist().contains(opData.getCard().getCard_id())) {
					playerData.getQipenglist().add(opData.getCard().getCard_id());
				}
			}
			if(op==CphOp.CHIPAI) {
				//能够碰牌却弃吃
				if(!playerData.getQichilist().contains(opData.getCard().getCard_id())) {
					playerData.getQichilist().add(opData.getCard().getCard_id());
				}
			}
			
		}
		Map<Integer,ReqOp> choosemap=phzGameBase.getChoosemap();
		choosemap.put(uid, reqGuopai);
		controller.getWebClient().sendMessage(Message.build(PHZCMD.RES_CPHOP, Resp.build(Code.OK, "操作成功")));
	}

	public static void autoCheckCph(Room room) {
		PhzGameBase phzGameBase=(PhzGameBase) room.getGameBase();
		Map<Integer,List<CphOpData>> fanpaiOplistmap=phzGameBase.getOplistmap();
		Map<Integer,ReqOp> choosemap=phzGameBase.getChoosemap();
		List<Integer> canhu_uids=calCanOpUids(fanpaiOplistmap,CphOp.HU);
		OpData fanpai = phzGameBase.getFanpai();
		if(!canhu_uids.isEmpty()) {
			ReqHupai hupai=(ReqHupai) effectOp(room,fanpai,CphOp.HU,canhu_uids);
			if(hupai!=null) {
				phzGameBase.setDelayOp(null);
				if(fanpai.getBaipai_uid()!=null&&fanpai.getBaipai_uid().intValue()==hupai.getUid()) {
					hupai(room,hupai.getUid(),null);
				}else {
					hupai(room,hupai.getUid(),fanpai);
				}
				return;
			}
		}
		if(choosemap.keySet().containsAll(canhu_uids)) {
			List<Integer> canpeng_uids=calCanOpUids(fanpaiOplistmap,CphOp.PENGPAI);
			if(!canpeng_uids.isEmpty()) {
				ReqPengpai peng=(ReqPengpai) effectOp(room,fanpai,CphOp.PENGPAI,canpeng_uids);
				if(peng!=null) {
					phzGameBase.setDelayOp(null);
					pengpai(room,peng);
					return;
				}
			}
			if(choosemap.keySet().containsAll(canpeng_uids)) {
				List<Integer> canchi_uids=calCanOpUids(fanpaiOplistmap,CphOp.CHIPAI);
				if(!canchi_uids.isEmpty()) {
					ReqChipai chi=(ReqChipai) effectOp(room,fanpai,CphOp.CHIPAI,canchi_uids);
					if(chi!=null) {
						phzGameBase.setDelayOp(null);
						chipai(room,chi);
						return;
					}
				}
				int guo_size=calGuopaiSize(choosemap);
				if(guo_size==fanpaiOplistmap.size()&&guo_size>0) {
					phzGameBase.setDelayOp(null);
					guopai(room);
					return;
				}
			}
		}
	}

	public static int calHuxiByPlayerData(Room room,PlayerData playerData) {
		int huxi=0;
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		HupaiData hupaiData= phzGameBase.getHupaiData();
		List<List<Card>> hands=hupaiData.getHupailist();
		System.out.println("服务器计算手牌的胡牌数据:"+hands);
		List<Data> baipais=playerData.getBaipais();
		int hand_huxi=calHandHuxi(room,hands,playerData.getUid());
		int baipai_huxi=calBaipaiHuXi(baipais);
		System.out.println("计算手牌胡息"+hand_huxi);
		System.out.println("计算摆牌胡息"+baipai_huxi);
		huxi+=hand_huxi;
		huxi+=baipai_huxi;
		return huxi;
	}

	private static int calBaipaiHuXi(List<Data> baipais) {
		int huxi=0;
		for(Data data:baipais) {
			if(data.getType()==DataType.TIPAI) {
				TipaiData tipaiData = (TipaiData) data;
				List<Card> cards=tipaiData.getTipailist();
				int color=cards.get(0).getColor();
				if(color==100) {
					huxi+=9;
				}else if(color==200) {
					huxi+=12;
				}
			}
			if(data.getType()==DataType.PAOPAI) {
				PaopaiData paopaiData=(PaopaiData) data;
				List<Card> cards=paopaiData.getPaopailist();
				int color=cards.get(0).getColor();
				if(color==100) {
					huxi+=6;
				}else if(color==200) {
					huxi+=9;
				}
			}
			if(data.getType()==DataType.WEIPAI) {
				WeipaiData weipaiData = (WeipaiData) data;
				List<Card> cards=weipaiData.getWeipailist();
				int color=cards.get(0).getColor();
				if(color==100) {
					huxi+=3;
				}else if(color==200) {
					huxi+=6;
				}
			}
			if(data.getType()==DataType.CHOUWEI) {
				ChouweiData chouweiData = (ChouweiData) data;
				List<Card> cards=chouweiData.getChouweilist();
				int color=cards.get(0).getColor();
				if(color==100) {
					huxi+=3;
				}else if(color==200) {
					huxi+=6;
				}
			}
			if(data.getType()==DataType.PENGPAI) {
				PengData pengData = (PengData) data;
				List<Card> cards=pengData.getPengpailist();
				int color=cards.get(0).getColor();
				if(color==100) {
					huxi+=1;
				}else if(color==200) {
					huxi+=3;
				}
			}
			if(data.getType()==DataType.CHIPAI) {
				ChiData chiData = (ChiData) data;
				List<Card> cards=chiData.getChipailist();
				if(CardUtil.tonghuaerqishi(cards)) {
					if(cards.get(0).getColor()==100) {
						huxi+=3;//3张小2710牌 3胡息
					}else if(cards.get(0).getColor()==200) {
						huxi+=6;//3张大2710牌 6胡息
					}
				}
				
				if(CardUtil.tonghuaeyiersan(cards)) {
					if(cards.get(0).getColor()==100) {
						huxi+=3;//3张小123牌 3胡息
					}else if(cards.get(0).getColor()==200) {
						huxi+=6;//3张大123牌 6胡息
					}
				}
			}
		}
		return huxi;
	}

	public static void reqHupaiGuo(Room room, LogicController controller, ReqHupaiGuo reqHupaiGuo) {
		int uid=controller.getId();
		PhzGameBase phzGameBase=(PhzGameBase) room.getGameBase();
		Map<Integer,ReqOp> choosemap=phzGameBase.getChoosemap();
		choosemap.put(uid, reqHupaiGuo);
		controller.getWebClient().sendMessage(Message.build(PHZCMD.RES_CPHOP, Resp.build(Code.OK, "操作成功")));		
	}

	public static CphOpData doFangpaofaHupaiOp(Room room, Card card, int uid) {
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PhzConfig phzConfig = (PhzConfig) room.getGameConfig();
		int next_uid=LogicUtil.getNextPosByUid(room, uid);
		do {
			PlayerData playerData = phzGameBase.getPlayers().get(next_uid);
			if(!playerData.isQihu()) {
				//检测胡
				CphOpData hupaiOp=checkHupaiOp(playerData,card,phzConfig.getHupai_need());
				if(hupaiOp!=null) {
					return hupaiOp;
				}
			}
			next_uid=LogicUtil.getNextPosByUid(room, next_uid);
		}while(next_uid!=uid);
		return null;
	}

	public static CphOpData fangpaofaHupaiOp(Room room, Card card, int uid) {
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PhzConfig phzConfig = (PhzConfig) room.getGameConfig();
		PlayerData playerData = phzGameBase.getPlayers().get(uid);
		if(!playerData.isQihu()) {
			//检测胡
			CphOpData hupaiOp=checkHupaiOp(playerData,card,phzConfig.getHupai_need());
			if(hupaiOp!=null) {
				return hupaiOp;
			}
		}
		return null;
	}

//	public static Map<Integer, List<CphOpData>> doMopaiBaipaiAndHupaiOps(Room room, int uid, Card card) {
//		Map<Integer, List<CphOpData>> cphOps=new HashMap<Integer, List<CphOpData>>();
//		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
//		PhzConfig phzConfig = (PhzConfig) room.getGameConfig();
//		int next_uid=uid;
//		do {
//			PlayerData playerData = phzGameBase.getPlayers().get(next_uid);
//			List<CphOpData> cphOpDatas=new ArrayList<>();
//			if(!playerData.isQihu()) {
//				//检测胡
//				CphOpData hupaiOp=checkHupaiOp(playerData,uid==next_uid?null:card,phzConfig.getHupai_need());
//				if(hupaiOp!=null) {
//					cphOpDatas.add(hupaiOp);
//				}
//			}
//			if(!cphOpDatas.isEmpty()) {
//				cphOpDatas.add(new CphOpData(CphOp.PASS,next_uid));
//				cphOps.put(next_uid, cphOpDatas);
//			}
//			next_uid=LogicUtil.getNextPosByUid(room, next_uid);
//		}while(next_uid!=uid);
//		return cphOps;
//	}
	
	public static Map<Integer, List<CphOpData>> doMopaiHupaiOps(Room room, int uid, Card card) {
		Map<Integer, List<CphOpData>> cphOps=new HashMap<Integer, List<CphOpData>>();
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PhzConfig phzConfig = (PhzConfig) room.getGameConfig();
		int next_uid=uid;
		do {
			PlayerData playerData = phzGameBase.getPlayers().get(next_uid);
			List<CphOpData> cphOpDatas=new ArrayList<>();
			if(!playerData.isQihu()) {
				//检测胡
				CphOpData hupaiOp=checkHupaiOp(playerData,card,phzConfig.getHupai_need());
				if(hupaiOp!=null) {
					cphOpDatas.add(hupaiOp);
				}
			}
			if(!cphOpDatas.isEmpty()) {
				cphOpDatas.add(new CphOpData(CphOp.PASS,next_uid));
				cphOps.put(next_uid, cphOpDatas);
			}
			next_uid=LogicUtil.getNextPosByUid(room, next_uid);
		}while(next_uid!=uid);
		return cphOps;
	}

	public static void paopai(Room room, int uid) {
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PlayerData playerData = phzGameBase.getPlayers().get(uid);
		if(playerData.paoPaiSize()>=2) {
			System.out.println("2跑不需要出牌");
			int next_uid=LogicUtil.getNextPosByUid(room, uid);
			phzGameBase.setDelayOp(new DelayOp(next_uid, DelayType.AUTO_MOPAI, DelayTime.AUTO_MOPAI_DELAY));		
			return;
		}
		RoomUtil.notifyOutCard(room, uid);		
	}

	public static void tipai(Room room, int uid) {
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PlayerData playerData = phzGameBase.getPlayers().get(uid);
		if(playerData.paoPaiSize()>=2) {
			System.out.println("2跑不需要出牌");
			int next_uid=LogicUtil.getNextPosByUid(room, uid);
			phzGameBase.setDelayOp(new DelayOp(next_uid, DelayType.AUTO_MOPAI, DelayTime.AUTO_MOPAI_DELAY));		
			return;
		}
		RoomUtil.notifyOutCard(room, uid);		
	}

	public static void weipai(Room room, int uid) {
		RoomUtil.notifyOutCard(room, uid);		
	}

	public static void chouwei(Room room, int uid) {
		RoomUtil.notifyOutCard(room, uid);			
	}
	
	public static Map<Integer, List<CphOpData>> doSelftMopaiBaipaiAndHupaiOps(Room room, int uid, Card card) {
		Map<Integer, List<CphOpData>> cphOps=new HashMap<Integer, List<CphOpData>>();
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PhzConfig phzConfig = (PhzConfig) room.getGameConfig();
		PlayerData playerData = phzGameBase.getPlayers().get(uid);
		List<CphOpData> cphOpDatas=new ArrayList<>();
		if(!playerData.isQihu()) {
			//检测胡
			CphOpData hupaiOp=checkHupaiOp(playerData,card!=null?card:null,phzConfig.getHupai_need());
			if(hupaiOp!=null) {
				cphOpDatas.add(hupaiOp);
			}
		}
		if(!cphOpDatas.isEmpty()) {
			cphOpDatas.add(new CphOpData(CphOp.PASS,uid));
			cphOps.put(uid, cphOpDatas);
		}
		return cphOps;
	}

	public static void mopai(Room room, int uid, Card card, OpData opData,boolean checkhu) {
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		PlayerData playerData = phzGameBase.getPlayers().get(uid);
		Data data =RoomUtil.doBaipai(room,card,uid,OpType.MOPAI);
		if(data!=null) {
			phzGameBase.getFanpai().setBaipai_uid(data.getUid());
			playerData.setOut_count(playerData.getOut_count()+1);//出牌次数+1
			if(data instanceof PaopaiData) {
				PaopaiData paopaiData = (PaopaiData) data;
				phzGameBase.setDelayOp(new DelayOp(paopaiData.getUid(), DelayType.AUTO_PAOPAI, DelayTime.AUTO_PAOPAI_DELAY, paopaiData,OpType.MOPAI,card));
			}else if(data instanceof TipaiData) {
				TipaiData tipaiData=(TipaiData) data;
				phzGameBase.setDelayOp(new DelayOp(tipaiData.getUid(), DelayType.AUTO_TIPAI, DelayTime.AUTO_TIPAI_DELAY, tipaiData,OpType.MOPAI,card));
			}else if(data instanceof WeipaiData) {
				WeipaiData weipaiData=(WeipaiData) data;
				phzGameBase.setDelayOp(new DelayOp(weipaiData.getUid(), DelayType.AUTO_WEIPAI, DelayTime.AUTO_WEIPAI_DELAY, weipaiData,OpType.MOPAI,card));
			}else if(data instanceof ChouweiData) {
				ChouweiData chouweiData=(ChouweiData) data;
				phzGameBase.setDelayOp(new DelayOp(chouweiData.getUid(), DelayType.AUTO_CHOUWEI, DelayTime.AUTO_CHOUWEI_DELAY, chouweiData,OpType.MOPAI,card));
			}
			return;
		}
		
		Map<Integer,List<CphOpData>> map=RoomUtil.doCphOps(room,card,uid,OpType.MOPAI,checkhu);
		if(!map.isEmpty()) {
			autoCph(room,map);
			return;
		}
		playerData.setOut_count(playerData.getOut_count()+1);//出牌次数+1
		playerData.getOp_datas().add(opData);
		int next_uid=LogicUtil.getNextPosByUid(room, uid);
		phzGameBase.setDelayOp(new DelayOp(next_uid, DelayType.AUTO_MOPAI, DelayTime.AUTO_MOPAI_DELAY));		
	}
	
	
	public static void autoCph(Room room, Map<Integer, List<CphOpData>> map) {
		PhzGameBase phzGameBase = (PhzGameBase) room.getGameBase();
		phzGameBase.getOplistmap().clear();
		phzGameBase.getChoosemap().clear();
		phzGameBase.getOplistmap().putAll(map);
		phzGameBase.setStep(2);
		for(Entry<Integer,List<CphOpData>>entry:map.entrySet()) {
			int cph_uid=entry.getKey();
			PlayerData pData=phzGameBase.getPlayers().get(cph_uid);
			pData.setLast_cphop_time(System.currentTimeMillis());
			List<CphOpData> oplist=new ArrayList<>();
			oplist.addAll(entry.getValue());
			LogicController logicController = room.getAllControllers().get(cph_uid);
			logicController.getWebClient().sendMessage(Message.build(PHZCMD.NOTIFY_CHPOP, Resp.build(Code.OK, "进行吃碰胡操作",PackageUtil.packageNotifyCphOp(room,cph_uid,oplist))));
		}		
		phzGameBase.setDelayOp(new DelayOp(phzGameBase.getDispatch_uid(), DelayType.CPH_CHECK, DelayTime.CPH_CHECK_DELAY));
	}

}
